package com.mycat.manager.content;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mycat.common.util.CommonUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.gson.Gson;

/**
 * AOP日志管理
 * 
 * @author Roger
 */
@Aspect
@Component
public class AOPAdvice {

	private static final Logger logger = LoggerFactory
			.getLogger(AOPAdvice.class);

	/**
	 * 配置切入点
	 */
	@Pointcut("execution(public * com.mycat.manager.controller.help.*.*(..))")
	private void outputLogMethod1() {
	}

	/**
	 * 配置切入点
	 */
	@Pointcut("execution(public * com.mycat.manager.controller.test.*.*(..))")
	private void test() {
	}

	/**
	 * 在方法之前执行一段逻辑
	 * 
	 * @param joinPoint
	 *            被拦截接口的入参
	 */
	@Before("outputLogMethod1() || test()")
	public void beforeAdvice(JoinPoint joinPoint) {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes sra = (ServletRequestAttributes) ra;
		HttpServletRequest request = sra.getRequest();
		
		logger.info("请求地址 : " + request.getRequestURI().toString());
		logger.info("请求方法 : " + joinPoint.getSignature().getDeclaringTypeName()
				+ "." + joinPoint.getSignature().getName() + "()");

		Object[] params = joinPoint.getArgs();

		if (null != params) {
			// 输入参数
			StringBuffer inputParam = new StringBuffer();
			Gson gson = new Gson();
			for (int i = 0; i < params.length; i++) {
				Object param = params[i];
				if (null != param) {
					if (!CommonUtil.isBaseType(param)) {
						if (param instanceof HttpServletRequest) {
							continue;
						} else if (param instanceof HttpServletResponse) {
							continue;
						} else if (param instanceof Model) {
							continue;
						} else {
							inputParam.append(String.format(" [%s]", i));
							inputParam.append(String.format("[%s]", param.getClass().getName()));
							if (i == params.length - 1) {
								inputParam.append("-->").append(gson.toJson(param).toString()).append(" ");
							} else {
								inputParam.append("-->").append(gson.toJson(param).toString()).append(" , ");
							}
						}
					} else {
						inputParam.append(String.format("[%s]", i));
						if (i == params.length - 1) {
							inputParam.append("-->").append(param).append(" ");
						} else {
							inputParam.append("-->").append(param).append(" , ");
						}
					}
				} else {
					logger.info("请求参数 : 无 .");
				}
			}
			logger.info("请求参数 : 【" + inputParam.toString() + "】");
		} else {
			logger.info("请求参数 : 无 .");
		}
	}

	/**
	 * 在方法之后执行一段逻辑
	 * 
	 * @param joinPoint
	 *            被拦截接口的入参
	 */
	@After("outputLogMethod1()")
	public void afterAdvice(JoinPoint joinPoint) {
	}

	/**
	 * 在请求前后执行一段逻辑
	 * 
	 * @param pjp
	 *            被拦截接口的入参
	 * @return
	 * @throws Throwable
	 */
	@Around("outputLogMethod1() || test()")
	public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
		// 调用核心逻辑
		Object retVal = pjp.proceed();
		try {
			String str = "";
			if (CommonUtil.isNotEmpty(retVal)) {
				Gson gson = new Gson();
				str = gson.toJson(retVal);
				logger.info("响应数据  : " + str);
			} else {
				logger.info("返回类型是 Void");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return retVal;
	}
}
